<template>
  <div>左边：{{ left }}</div>
  <div>上面：{{ top }}</div>

  <div
    ref="draggable"
    class="draggable"
    @mousedown="startDrag"
    @touchstart="startDrag"
    :style="{ transform: `translate(${left}px, ${top}px)` }"
  >
    拖动我
  </div>
</template>

<script setup>
import { ref } from "vue";

const draggable = ref(null);
const startX = ref(0);
const startY = ref(0);
const left = ref(0);
const top = ref(0);

const startDrag = (event) => {
  // 阻止默认行为，如文本选中和图片拖动
  event.preventDefault();

  // 保存鼠标或触摸的初始位置
  startX.value = event.x;
  startY.value = event.y;

  // 添加事件监听
  window.addEventListener("mousemove", doDrag);
  window.addEventListener("touchmove", doDrag);
  window.addEventListener("mouseup", stopDrag);
  window.addEventListener("touchend", stopDrag);
};

const doDrag = (event) => {
  // 计算移动的距离
  const currentX = event.x;
  const currentY = event.y;
  const diffX = currentX - startX.value;
  const diffY = currentY - startY.value;

  // 更新元素位置
  left.value = left.value + diffX;
  top.value = top.value + diffY;

  // 更新初始位置
  startX.value = currentX;
  startY.value = currentY;
};

const stopDrag = () => {
  // 移除事件监听
  window.removeEventListener("mousemove", doDrag);
  window.removeEventListener("touchmove", doDrag);
  window.removeEventListener("mouseup", stopDrag);
  window.removeEventListener("touchend", stopDrag);
};
</script>

<style>
.draggable {
  /* position: absolute; */
  width: 200px;
  height: 100px;
  cursor: move;
  background-color: #ddd;
  text-align: center;
  line-height: 100px;
}
</style>
